/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package compilador.analisadorLexico;

import compilador.tabelaDeSimbolos.Identificador;
import compilador.analisadorLexico.automatos.*;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author Henrique
 */
public class AnalisadorLexico {
    
    public static final boolean DEBUG = false;
    
    private CodeReader reader;

    private List<Token> tokens;
    private List<TokenErro> erros;
    private IAutomato espaco;
    private IAutomato comentario;
    private IAutomato delimitador;
    private IAutomato digito;
    private IAutomato identificador;
    private IAutomato letra;
    private IAutomato numero;
    private IAutomato charConst;
    private IAutomato operador;
    private IAutomato erroLexico;
    //private Simbolos simbolos;

    
    public AnalisadorLexico(String code) {
        this.reader = new CodeReader(code);
        
        this.tokens = new ArrayList<Token>();
        this.erros = new ArrayList<TokenErro>();
        
        //this.simbolos = new Simbolos();
        
        this.espaco = new AutomatoEspaco(reader);
        this.comentario = new AutomatoComentario(reader);
        this.delimitador = new AutomatoDelimitador(reader);
        this.digito = new AutomatoDigito(reader);
        this.identificador = new AutomatoIdentificador(reader);
        this.letra = new AutomatoLetra(reader);
        this.numero = new AutomatoNumero(reader);
        this.operador = new AutomatoOperador(reader);
        this.charConst = new AutomatoCharConst(reader);

        this.erroLexico = new AutomatoErro(reader);
    }

    public List<Token> getTokens() {
        return tokens;
    }

    public List<TokenErro> getErros() {
        return erros;
    }
    
    public void extraiTokens(){
                 
        while(reader.hasChar()){
            //System.out.println("Start Token " + reader.next());
            
            Token token = null;
            espaco.extraiToken();
            
            token = comentario.extraiToken();
            if(token == null)
                token = delimitador.extraiToken();
            if(token == null)
                token = identificador.extraiToken();
            if(token == null)
                token = letra.extraiToken();
            if(token == null)
                token = digito.extraiToken();
            if(token == null)
                token = numero.extraiToken();
            if(token == null)
                token = charConst.extraiToken();
            if(token == null)
                token = operador.extraiToken();
            if(token == null){
                token = erroLexico.extraiToken();
            }
            
            insertToken(token);
        }
        
    }
    
    
    private void insertToken(Token token){
        if(token == null)
            return;
        
        if(AnalisadorLexico.DEBUG)
            System.out.println(token);
        
        if(token.getTokenClass().equals(TokenClass.ERRO_LEXICO)){
            TokenErro tokenErro = null;
            
            if(token instanceof TokenErro)
                tokenErro = (TokenErro) token;
            else
                tokenErro =  new TokenErro(token.getAtributo(), token.getLinha(), "Erro Léxico");
            
            erros.add(tokenErro);
        }else{
            tokens.add(token);
        }
        
        if(token.getTokenClass().equals(TokenClass.IDENTIFICADOR)){
            Identificador id = null;
            if(token.getAtributo() instanceof Identificador)
                id = (Identificador)token.getAtributo();
            else
                id = new Identificador(token.getAtributo().toString());
            
            /* REMOVIDO!!!!!!!!!!!!!
            /*
             * caso o identificador já exista na tabela de símbolos
             * o atributo do token passa a referenciar o atributo que existe
             * na tabela
             * 
             * caso contrário o identificador é adicionado à tabela de símbolos
             */
            /*
            if(simbolos.containsKey(id.getNome()))
                token.setAtributo(simbolos.get(id.getNome()));
            else
                simbolos.put(id);*/
        }
        
    }
    
    /*public static void main (String[] args){
        String code = "13s 13 s _1s1s\n\n" +
                " blabla class /*hdsdghdgshghsd 'dshgdhds' \n" +
                "1212s1if+/-0.1";
        
        System.out.println("CODE: \n" + code + "\nEND_CODE\n");
        
        AnalisadorLexico anLex = new AnalisadorLexico(code);
        anLex.extraiTokens();
        
        System.out.println("TOKENS");
        for(Token t : anLex.getTokens()){
            System.out.println(t);
        }
        
        System.out.println("ERROS LÉXICOS");
        for(Token t : anLex.getErros()){
            System.out.println(t);
        }
        
        System.out.println("SÍMBOLOS");
        for(String key : anLex.getSimbolos().keySet()){
            System.out.println(anLex.getSimbolos().get(key));
        }
    }*/
    
}
